package com.michael.retail.auth.service;

import com.michael.retail.auth.entity.OAuth2UserDetails;
import com.michael.retail.commons.pojo.enums.OAuth2ClientEnum;
import com.michael.retail.commons.pojo.global.R;
import com.michael.retail.sys.api.feign.SysUserFeign;
import com.michael.retail.sys.api.pojo.entity.SysUser;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Objects;


/**
 * 类功能描述:
 * <pre>
 *   自定义 UserDetailsService
 *   用于加载登录用户信息
 * </pre>
 *
 * @author Michael
 * @version 1.0
 * @date 2021/7/5 19:12
 */
@SuppressWarnings("AlibabaClassNamingShouldBeCamel")
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OAuth2UserDetailsService implements UserDetailsService {

    private final SysUserFeign sysUserFeign;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 1. 检查用户从哪个应用过来的 clientId (请求头信息等方式)
        // 2. 根据 clientId 调用对应的获取用户的方法
        // 3. 判断用户状态是否正常

        String clientId = OAuth2ClientEnum.ADMIN.getClientId();
        OAuth2UserDetails oauth2User = getUserDetails(clientId, username);

        if (oauth2User == null || oauth2User.getId() == null) {
            return oauth2User;
        } else if (!oauth2User.isEnabled()) {
            throw new DisabledException("账户已被禁用!");
        } else if (!oauth2User.isAccountNonLocked()) {
            throw new LockedException("账号已被锁定!");
        } else if (!oauth2User.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期!");
        } else if (!oauth2User.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException("凭证已过期!");
        }

        return oauth2User;
    }

    /** 根据不同的应用来源调用不同的方法获取用户信息并封装为 OAuth2UserDetails 对象 */
    private OAuth2UserDetails getUserDetails(String clientId, String username) {
        OAuth2ClientEnum client = OAuth2ClientEnum.getByClientId(clientId);
        OAuth2UserDetails details = null;
        switch (Objects.requireNonNull(client)) {
            case ADMIN:
                R<SysUser> result = sysUserFeign.getUserByUsername(username);
                if (R.succeed().getCode().equals(result.getCode())) {
                    SysUser sysUser = result.getData();
                    if (sysUser == null) {
                        throw new UsernameNotFoundException("不存在的用户");
                    }
                    details = new OAuth2UserDetails(sysUser);
                }
                break;
            case MINWX:
                break;
            case TEST:
                break;
            default:
                break;
        }
        return details;
    }
}
